package com.example.demo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;
import org.json.JSONException;
import org.json.JSONObject;
import org.webrtc.AudioSource;
import org.webrtc.AudioTrack;
import org.webrtc.Camera1Enumerator;
import org.webrtc.Camera2Enumerator;
import org.webrtc.CameraEnumerator;
import org.webrtc.DataChannel;
import org.webrtc.DefaultVideoDecoderFactory;
import org.webrtc.DefaultVideoEncoderFactory;
import org.webrtc.EglBase;
import org.webrtc.IceCandidate;
import org.webrtc.MediaConstraints;
import org.webrtc.MediaStream;
import org.webrtc.PeerConnection;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.RtpReceiver;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSource;
import org.webrtc.VideoTrack;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


public class MainActivity extends AppCompatActivity {

    // 用于创建对等连接的工厂对象
    private PeerConnectionFactory peerConnectionFactory;
    // 本地视频轨道对象
    private VideoTrack localVideoTrack;
    // 用于显示本地视频的视图对象
    private SurfaceViewRenderer localVideoView;
    // 用于显示远程视频的视图对象
    private SurfaceViewRenderer remoteVideoView;
    // 用于OpenGL ES上下文管理的对象
    private EglBase rootEglBase;
    // WebSocket 客户端
    private MyWebSocketClient webSocketClient;
    // 输入框
    private EditText editTextMessage;
    // 发送消息按钮
    private Button buttonSend;
    // 开启视频按钮
    private Button buttonStartVideo;
    // 关闭视频按钮
    private Button buttonStopVideo;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置当前Activity的布局文件
        setContentView(R.layout.activity_main);

        // 从布局文件中找到本地视频视图控件并赋值给localVideoView
        localVideoView = findViewById(R.id.local_video_view);
        // 从布局文件中找到远程视频视图控件并赋值给remoteVideoView
        remoteVideoView = findViewById(R.id.remote_video_view);
        // 找到输入框
        editTextMessage = findViewById(R.id.editTextMessage);
        // 找到发送消息按钮
        buttonSend = findViewById(R.id.buttonSend);
        // 找到开启视频按钮
        buttonStartVideo = findViewById(R.id.buttonStartVideo);
        // 找到关闭视频按钮
        buttonStopVideo = findViewById(R.id.buttonStopVideo);


        // 初始化EglBase，用于OpenGL ES的上下文管理，WebRTC的视频渲染需要使用OpenGL ES
        rootEglBase = EglBase.create();
        // 初始化本地视频视图的OpenGL ES上下文
        localVideoView.init(rootEglBase.getEglBaseContext(), null);
        // 初始化远程视频视图的OpenGL ES上下文
        remoteVideoView.init(rootEglBase.getEglBaseContext(), null);

        // 创建PeerConnectionFactory的初始化选项，传入当前Activity的上下文
        PeerConnectionFactory.InitializationOptions initializationOptions =
                PeerConnectionFactory.InitializationOptions.builder(this)
                        .createInitializationOptions();
        // 使用初始化选项初始化PeerConnectionFactory
        PeerConnectionFactory.initialize(initializationOptions);

        // 创建PeerConnectionFactory的选项对象
        PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
        // 创建默认的视频编码器工厂，传入EglBase上下文，并设置一些编码相关的参数（如是否硬件编码等）
        DefaultVideoEncoderFactory defaultVideoEncoderFactory = new DefaultVideoEncoderFactory(
                rootEglBase.getEglBaseContext(), true, true);
        // 创建默认的视频解码器工厂，传入EglBase上下文
        DefaultVideoDecoderFactory defaultVideoDecoderFactory = new DefaultVideoDecoderFactory(rootEglBase.getEglBaseContext());
        // 使用PeerConnectionFactory的构建器，设置选项、视频编码器工厂和视频解码器工厂，然后创建PeerConnectionFactory实例
        peerConnectionFactory = PeerConnectionFactory.builder()
                .setOptions(options)
                .setVideoEncoderFactory(defaultVideoEncoderFactory)
                .setVideoDecoderFactory(defaultVideoDecoderFactory)
                .createPeerConnectionFactory();

        // 视频采集器相关方法：
        // 调用createVideoCapturer方法创建视频采集器，该方法会根据设备支持的情况（Camera2或Camera1）创建相应的采集器
        VideoCapturer videoCapturer = createVideoCapturer();
        // 使用PeerConnectionFactory创建视频源，传入前面创建的视频采集器
        VideoSource videoSource = peerConnectionFactory.createVideoSource(false);
        // 创建本地视频轨道，指定一个ID为"100"，并关联前面创建的视频源
        localVideoTrack = peerConnectionFactory.createVideoTrack("100", videoSource);
        // 将本地视频轨道添加到本地视频显示视图，以便在界面上显示本地采集的视频
        localVideoTrack.addSink(localVideoView);

        // 创建音频流
        // 创建音频源，传入一个MediaConstraints对象，用于设置音频的一些约束条件（如音频质量等）
        AudioSource audioSource = peerConnectionFactory.createAudioSource(new MediaConstraints());
        // 创建音频轨道，指定一个ID为"101"，并关联前面创建的音频源
        AudioTrack audioTrack = peerConnectionFactory.createAudioTrack("101", audioSource);

        // 创建MediaStream并添加音视频轨道
        // 创建本地媒体流，指定一个ID为"102"
        MediaStream mediaStream = peerConnectionFactory.createLocalMediaStream("102");
        // 将本地视频轨道添加到本地媒体流中
        mediaStream.addTrack(localVideoTrack);
        // 将本地音频轨道添加到本地媒体流中
        mediaStream.addTrack(audioTrack);


        // 以下是一个简单的PeerConnection创建示例，但不完整，仅为演示
        // 这里先不创建 PeerConnection 的 RTC 配置对象


        // 创建并启动 WebSocket 客户端
        try {
            webSocketClient = new MyWebSocketClient(new URI("wss://192.168.10.146:8081/call"));
            webSocketClient.connect();
        } catch (URISyntaxException e) {

            Log.d("websocket",e.getLocalizedMessage());
            e.printStackTrace();
            }


        // 为发送消息按钮添加点击事件监听器
        buttonSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = editTextMessage.getText().toString();
                sendMessage(message);
                editTextMessage.setText("");
            }
        });


        // 为开启视频按钮添加点击事件监听器
        buttonStartVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startVideo();
    }
        });


        // 为关闭视频按钮添加点击事件监听器
        buttonStopVideo.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                stopVideo();
            }
        });
    }


    // 创建视频采集器的方法
    private VideoCapturer createVideoCapturer() {
        VideoCapturer videoCapturer;
        // 检查设备是否支持Camera2
        if (Camera2Enumerator.isSupported(this)) {
            // 如果支持，创建Camera2Enumerator对象
            Camera2Enumerator enumerator = new Camera2Enumerator(this);
            // 调用createCameraCapturer方法创建视频采集器
            videoCapturer = createCameraCapturer(enumerator);
        } else {
            // 如果不支持Camera2，创建Camera1Enumerator对象，并设置前置摄像头优先
            Camera1Enumerator enumerator = new Camera1Enumerator(true);
            // 调用createCameraCapturer方法创建视频采集器
            videoCapturer = createCameraCapturer(enumerator);
        }
        return videoCapturer;
    }

    // 根据CameraEnumerator创建视频采集器的方法
    private VideoCapturer createCameraCapturer(CameraEnumerator enumerator) {
        // 获取设备名称数组
        final String[] deviceNames = enumerator.getDeviceNames();

        // 遍历设备名称数组，优先查找前置摄像头
        for (String deviceName : deviceNames) {
            if (enumerator.isFrontFacing(deviceName)) {
                // 创建视频采集器，如果创建成功则返回
                VideoCapturer capturer = enumerator.createCapturer(deviceName, null);
                if (capturer!= null) {
                    return capturer;
                }
            }
        }

        // 如果没有找到前置摄像头，遍历设备名称数组，查找后置摄像头
        for (String deviceName : deviceNames) {
            if (!enumerator.isFrontFacing(deviceName)) {
                // 创建视频采集器，如果创建成功则返回
                VideoCapturer capturer = enumerator.createCapturer(deviceName, null);
                if (capturer!= null) {
                    return capturer;
                }
            }
        }
        // 如果都没有找到合适的摄像头，返回null
        return null;
    }


    // 发送消息到 WebSocket 服务器
    private void sendMessage(String message) {
        if (webSocketClient!= null && webSocketClient.isOpen()) {

//           {"id":"chat","data":"fsdf","role":"presenter","token":"eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImEiLCJleHAiOjE3Mzc0NjQzMTJ9.KGvrLNjwzJMVFHDX3sgiPUoRSSBCkAr1i3t_S7X1ov8"}

            //

            JSONObject jsonObject = new JSONObject();
            try {
                jsonObject.put("id","chat");
                jsonObject.put("role","presenter");
                jsonObject.put("token","eyJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6ImEiLCJleHAiOjE3Mzc0NjQzMTJ9.KGvrLNjwzJMVFHDX3sgiPUoRSSBCkAr1i3t_S7X1ov8");
                jsonObject.put("data",message);

            } catch (JSONException e) {
                e.printStackTrace();
            }

            String s = jsonObject.toString();

            webSocketClient.send(s);
        } else {
            Log.e("MainActivity", "WebSocket not connected");
        }
    }


    // 开启视频
    private void startVideo() {
        Log.d("test","startVideo");
        if (localVideoTrack!= null) {
            localVideoTrack.setEnabled(true);
            localVideoTrack.addSink(localVideoView);
        }
    }


    // 关闭视频
    private void stopVideo() {
        if (localVideoTrack!= null) {
            localVideoTrack.setEnabled(false);
            localVideoTrack.removeSink(localVideoView);
        }
    }


    // 自定义 WebSocket 客户端
    private class MyWebSocketClient extends WebSocketClient {
        public MyWebSocketClient(URI serverUri) {
            super(serverUri, new org.java_websocket.drafts.Draft_6455(), null, 0);
            try {
                SSLContext sslContext = SSLContext.getInstance("TLS");
                sslContext.init(null, new TrustManager[]{new TrustAllManager()}, null);
                this.setSocket(sslContext.getSocketFactory().createSocket());
            } catch (Exception e) {
                Log.e("MainActivity", "SSL Context error", e);
            }
        }


        @Override
        public void onOpen(ServerHandshake handshakedata) {
            Log.d("MainActivity", "WebSocket opened");
        }


        @Override
        public void onMessage(String message) {
            Log.d("MainActivity", "Received message: "  + message);
            // 在这里可以根据收到的消息进行相应的处理，例如处理信令信息
        }


        @Override
        public void onClose(int code, String reason, boolean remote) {
            Log.d("MainActivity", "WebSocket closed");
        }


        @Override
        public void onError(Exception ex) {
            Log.e("MainActivity", "WebSocket error", ex);
        }
    }


    // 自定义的 TrustManager，接受所有证书，仅用于测试环境，不推荐用于生产环境
    private static class TrustAllManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }


        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        }


        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }


    // 新添加的方法，用于创建 PeerConnection.RTCConfiguration 对象
    private PeerConnection.RTCConfiguration createRTCConfiguration() {
        return new PeerConnection.RTCConfiguration(Arrays.asList(
                new PeerConnection.IceServer("stun:stun.l.google.com:19302")
        ));
    }


    // 可以在需要的时候调用 createRTCConfiguration 方法，例如在建立 PeerConnection 时
    private void establishPeerConnection() {
        PeerConnection.RTCConfiguration rtcConfiguration = createRTCConfiguration();
        PeerConnection peerConnection = peerConnectionFactory.createPeerConnection(rtcConfiguration, new PeerConnection.Observer() {
            // 当收到 ICE 候选者时调用此方法，将 ICE 候选者发送到对端
            @Override
            public void onIceCandidate(IceCandidate iceCandidate) {
                sendMessage(iceCandidate.toString());
            }

            // 当ICE候选者被移除时调用此方法，这里只是一个空实现
            @Override
            public void onIceCandidatesRemoved(IceCandidate[] iceCandidates) {

            }

            // 当添加远程媒体流时调用此方法，这里将远程视频轨道添加到远程视频显示视图中
            @Override
            public void onAddStream(MediaStream mediaStream) {
                // 处理远程媒体流添加
                VideoTrack remoteVideoTrack = mediaStream.videoTracks.get(0);
                remoteVideoTrack.addSink(remoteVideoView);
            }

            // 其他回调方法，这里暂时为空实现，实际应用中需要根据需求进行处理，如处理连接状态变化、信令变化等

            @Override
            public void onIceConnectionChange(PeerConnection.IceConnectionState iceConnectionState) {}

            @Override
            public void onIceConnectionReceivingChange(boolean b) {
            }


            @Override
            public void onIceGatheringChange(PeerConnection.IceGatheringState iceGatheringState) {}

            @Override
            public void onSignalingChange(PeerConnection.SignalingState signalingState) {}

            @Override
            public void onRemoveStream(MediaStream mediaStream) {}

            @Override
            public void onDataChannel(DataChannel dataChannel) {}

            @Override
            public void onRenegotiationNeeded() {}

            @Override
            public void onAddTrack(RtpReceiver rtpReceiver, MediaStream[] mediaStreams) {
            }
        });
    }
}